package com.tg.app.widget;

import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ListView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.tg.app.R;
import com.tg.app.adapter.CruisePrePositionAdapter;
import com.tg.app.bean.DevicePresetPoints;
import com.tg.app.camera.AVIOCTRLDEFs;
import com.tg.app.camera.Camera;
import com.tg.app.camera.CameraHelper;
import com.tg.app.util.ObjectBoxUtil;
import com.tg.appcommon.android.Packet;
import com.tg.appcommon.android.TGApplicationBase;
import com.tg.appcommon.android.TGLog;
import com.tange.base.toolkit.TGThreadPool;
import com.tg.appcommon.android.TGToast;
import com.tg.data.bean.DeviceSettingsInfo;
import com.tg.data.bean.DeviceSettingsInfo_;

import java.util.ArrayList;
import java.util.List;

import io.objectbox.Box;

/**
 * Describe:
 * Created by Rance Rang on 2019-12-21.
 * <p>
 * Copyright (c) Tange.Inc All rights reserved.
 */
public class PrePositionCruiseControlView extends PrePositionControlView{
    private static final String TAG = PrePositionCruiseControlView.class.getSimpleName();
    private CruisePrePositionAdapter adapter;


    public PrePositionCruiseControlView(Context context) {
        super(context);
        initView(context);
    }

    public PrePositionCruiseControlView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initView(context);
    }


    public PrePositionCruiseControlView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context);
    }

    public void init(){
        adapter.clearSelectedPresetPoints();
    }

    private void delResp(int result) {
        if (result == 0) {
            adapter.clearPointFromSelected();
        }
    }



    public void receiveIOCtrlData(int type, @NonNull byte[] data) {
        TGLog.d(TAG,"type = " + type);
        if (type == AVIOCTRLDEFs.TCI_CMD_GET_PSP_RESP) {
            pspType = CameraHelper.getPresetPointsTypeResp(data);
            TGLog.d(TAG,"pspType1 = " + pspType);
            if (isSupportWatchPos){
                CameraHelper.getWatchPosCMD(camera);
            }

            TGThreadPool.executeOnUiThread(() -> getPresetPointsResp(data));
        } else if (type == AVIOCTRLDEFs.TCI_CMD_GET_WATCHPOS_RESP){
            int num = Packet.byteArrayToInt_Little(data, 4);
            int times = Packet.byteArrayToInt_Little(data, 8);
            curSelectIdleTime = times;
            TGLog.d(TAG,"num = " + num + ", times = " +  ", adapter.isExistDevicePresetPoints(num) = " + adapter.isExistDevicePresetPoints(num));
            if (num != -1 && adapter.isExistDevicePresetPoints(num)){
                adapter.setWatchPosInfo(num, times);
            }
        } else if (type == AVIOCTRLDEFs.TCI_CMD_SET_COMMAND_RESP) {
            int command = CameraHelper.getSetCommand(data);
            int result = CameraHelper.getSetCommandResult(data);
            if (command == AVIOCTRLDEFs.TCI_CMD_SET_PSP || command == AVIOCTRLDEFs.TCI_CMD_SET_WATCHPOS_REQ) {
                TGToast.showToast(result == 0 ? R.string.camera_send_completed : R.string.camera_send_failed);
                if (command == AVIOCTRLDEFs.TCI_CMD_SET_PSP){
                    TGThreadPool.executeOnUiThread(() -> {
                        int num = adapter.getWatchPosNumber();
                        delResp(result);
                        if (result == 0){
                            ObjectBoxUtil.saveDevicePresetPoints(adapter.getPrePositions(), camera.uid);
                        }
                        if (num != -1 && !adapter.isExistDevicePresetPoints(num)){
                            CameraHelper.settWatchPosCMD(camera, 0, -1, 0);
                        }
                        TGLog.d(TAG,"num = " + num + ", times = " +  ", isExistDevicePresetPoints(num) = " + adapter.isExistDevicePresetPoints(num));
                    });
                }else {
                    TGLog.d(TAG, "adapter.getWatchPosNumber() = " + adapter.getWatchPosNumber());
                    if (isSupportWatchPos){
                        int num = adapter.getWatchPosNumber();
                        curSelectIdleTime = adapter.getIdleTime();
                        adapter.setWatchPosInfo(num, curSelectIdleTime);
                        CameraHelper.getWatchPosCMD(camera);
                    }
                }
            }
        }
    }

    private void getPresetPointsResp(byte[] data) {
        List<DevicePresetPoints> list = CameraHelper.getPresetPointsResp(data,false);
        TGLog.d(TAG,"size =" + list.size());
        if (list.size() > 0){
            for (DevicePresetPoints l:list){
                l.uuid = camera != null? camera.uid : l.uuid;
                TGLog.d(TAG,"num =" +l.num);
            }
        }
        Box<DeviceSettingsInfo> settingsInfoBox = ObjectBoxUtil.getDeviceSettingsInfo();
        if (settingsInfoBox != null) {
            DeviceSettingsInfo deviceSettingsInfo = settingsInfoBox.query().equal(DeviceSettingsInfo_.uuid, camera.uid).build().findFirst();
            adapter.setMaxNumber(deviceSettingsInfo == null? 0 : deviceSettingsInfo.maxPresetPoint);
        }else{
            adapter.setMaxNumber(0);
        }


        adapter.setData(list);

        if (camera != null){
            ObjectBoxUtil.saveDevicePresetPoints(list, camera.uid);
        }
    }


    @Override
    public void initView(Context context) {

        this.context = context;
        @SuppressLint("InflateParams") View view = LayoutInflater.from(context).inflate(R.layout.layout_pre_position_curise_ctl, null);
        addView(view);

        ListView listView = view.findViewById(R.id.pre_position_recyclerview);

        adapter = new CruisePrePositionAdapter(context, this);

        view.findViewById(R.id.rl_bkg).setVisibility(GONE);
        listView.setAdapter(adapter);

        listView.setOnItemClickListener((parent, view1, position, id) -> {
            setPrePositionFromClickItem(position);
        });
    }

    private void setPrePositionFromClickItem(int position){
        int state = getPrePositionState(position);
        if (state != 0){
            if (camera != null && camera.isConnected()){
                camera.sendPTZCMD(12, 0, (byte) (position + 1));
                TGThreadPool.executeOnUiThreadDelayed(new Runnable() {
                    @Override
                    public void run() {
                        TGToast.showToast(R.string.operation_successful);
                    }
                }, 100);
            }

        }
    }
    public void setCamera(@NonNull Camera camera) {
        this.camera = camera;
        adapter.setData(camera.uid);
        adapter.setCamera(camera);
        if (camera.isConnected()){
            CameraHelper.getPspCMD(camera);
        }
    }

    @Override
    public void click(int position) {
        createDialog(position);
    }

    @Override
    public void updateDelStatus() {}


    protected void deletedPresetPoints(int position) {
        if (!camera.isConnected()){
            TGToast.showToast(R.string.camera_send_failed);
            return;
        }

        int active_track = (int)TGApplicationBase.getInstance().getGlobalObject(TGApplicationBase.TRACK_NO);

        if (active_track == (short)65535 || active_track > 0){
            if (adapter.getPrePositions().size() <= 2){
                TGToast.showToast(R.string.delete_preposition_tip);
                return;
            }
        }

        adapter.addPointFromSelected(position);
        List<DevicePresetPoints> pointsList = new ArrayList<>();
        pointsList.add(adapter.getDevicePresetPoints(position));
        CameraHelper.deletedPresetPoints(camera, pspType, pointsList);
    }

    private void settWatchPosCMD(int position, int time){
        if (camera != null && camera.isConnected()){
            adapter.setWatchPosInfo(position + 1, time);
            CameraHelper.settWatchPosCMD(camera, 0, position + 1, time);
        }
    }

    private final PrePositionListDialog.PrePositionListDialogListener listener = (v, position, mode) -> {
        int id = v.getId();
        if (id == R.id.tv2){
            deletedPresetPoints(position);
        }else if (id == R.id.tv3){
            if (mode == 0){
                setPrePosition(position);
            }else if (mode == 1){
                settWatchPosCMD(position, curSelectIdleTime);
            }else if (mode == 2){
                settWatchPosCMD(-2, curSelectIdleTime);
            }
        }
    };

    private int getPrePositionState(int position){
        return adapter.getPrePositionState(position);
    }

    @SuppressLint("NotifyDataSetChanged")
    private void createDialog(int position) {
        PrePositionListDialog dialog = new PrePositionListDialog(context).builder(position, getPrePositionState(position));
        dialog.setListener(listener);
        dialog.show();
    }

    private void setPrePosition(int position){
        if(camera != null && camera.isConnected()){
            DevicePresetPoints prePosition = new DevicePresetPoints();
            prePosition.name = "";
            prePosition.pos = ptzPos;
            prePosition.num = position + 1;
            if (ptzPos!=null){
                prePosition.x = ptzPos.x;
                prePosition.y = ptzPos.y;
                prePosition.z = ptzPos.z;
            }
            prePosition.uuid = camera.uid;
            adapter.addData(prePosition);
            TGLog.d(TAG, "pspType = " + pspType);
            CameraHelper.setCruisePresetPoints(camera, pspType, prePosition);
            ObjectBoxUtil.saveDevicePresetPoints(adapter.getPrePositions(),camera.uid);
        }else {
            TGToast.showToast(R.string.camera_send_failed);
        }
    }
}
